package woaini.wind.bot.code.impl.qq.adapter;

import cn.hutool.core.util.StrUtil;
import io.github.kloping.qqbot.api.SendAble;
import io.github.kloping.qqbot.api.v2.FriendMessageEvent;
import io.github.kloping.qqbot.entities.ex.At;
import io.github.kloping.qqbot.entities.ex.AtAll;
import io.github.kloping.qqbot.entities.ex.PlainText;
import io.github.kloping.qqbot.entities.ex.msg.MessageChain;
import io.github.kloping.qqbot.http.data.V2MsgData;
import io.github.kloping.qqbot.impl.ListenerHost;
import woaini.wind.bot.core.event.enums.EventType;
import woaini.wind.bot.core.event.message.impl.PrivateMessageEvent;
import woaini.wind.bot.core.event.segment.Messages;
import woaini.wind.bot.core.event.base.Self;

import io.github.kloping.qqbot.Start0;
import io.github.kloping.qqbot.Starter;
import io.github.kloping.qqbot.api.Intents;
import io.github.kloping.qqbot.api.v2.GroupMessageEvent;
import woaini.wind.bot.code.impl.qq.config.QQBOTConfig;
import woaini.wind.bot.core.adapter.Adapter;
import woaini.wind.bot.core.bot.Bot;
import woaini.wind.bot.core.event.action.ActionRequest;
import woaini.wind.bot.core.event.action.ActionResponse;
import woaini.wind.bot.core.event.base.Event;
import woaini.wind.bot.core.event.segment.Segment;
import woaini.wind.bot.core.event.segment.impl.Text;

import java.util.HashMap;
import java.util.Map;

/**
 * QQ官方机器人用 websocket 用于接受时间和消息
 *
 * @see QQBOTWsAdapter
 * @author yefeng {@date 2024-09-23 17:45:56}
 */
public class QQBOTWsAdapter extends Adapter {

  private final QQBOTConfig qqbotConfig;

  private Starter starter;

  private static Map<String, String> GROUP_SEND_MESSAGE_HEADER;

  public static final Map<String, String> SEND_MESSAGE_HEADERS = new HashMap<>();

  static {
    SEND_MESSAGE_HEADERS.put("Content-Type", "application/json");
    SEND_MESSAGE_HEADERS.put("Accept-Encoding", "*/*");
  }

  public QQBOTWsAdapter(Bot bot) {
    super(bot);
    this.qqbotConfig = (QQBOTConfig) bot.getConfig();
    this.init();
  }

  public void init() {
    String appId = qqbotConfig.getAppId();
    String token = qqbotConfig.getToken();
    String secret = qqbotConfig.getSecret();
    starter = new Starter(appId, token, secret);
    // 设置接收的消息范围
    starter.getConfig().setCode(Intents.PUBLIC_INTENTS.and(Intents.GROUP_INTENTS));
    // 是否自动重新连接
    starter.setReconnect(true);
  }

  @Override
  public boolean connect() {
    starter.run();
    GROUP_SEND_MESSAGE_HEADER =
        starter
            .APPLICATION
            .INSTANCE
            .getContextManager()
            .getContextEntity(Start0.class)
            .getHeaders();
    // 注册时间
    this.registerListener();
    return true;
  }

  @Override
  public boolean reconnect() {
    return false;
  }

  public Event convert(FriendMessageEvent event) {

    PrivateMessageEvent privateMessageEvent = new PrivateMessageEvent();

    String id = event.getSubject().getId();
    privateMessageEvent.setUserId(id);
    privateMessageEvent.setId(event.getId());

    Self self = new Self();
    self.setPlatform(qqbotConfig.getPlatForm());
    self.setUserId(qqbotConfig.getSelfId());

    privateMessageEvent.setSelf(self);
    privateMessageEvent.setTime(0L);
    privateMessageEvent.setType(EventType.message);
    privateMessageEvent.setMessageId(event.getId());

    PlainText sendAble =
        (PlainText)
            event.getMessage().stream()
                .filter(d -> d instanceof PlainText)
                .findFirst()
                .orElse(null);
    if (sendAble != null) {
      privateMessageEvent.setAltMessage(sendAble.getText());
    }
    Messages messages = this.convert(event.getMessage());
    privateMessageEvent.setMessage(messages);

    return privateMessageEvent;
  }

  /**
   * 转换 群消息事件 为 Event
   *
   * @param event 事件
   * @author yefeng {@date 2025-01-22 15:43:46}
   * @since 1.0
   * @return {@link Event }
   */
  public Event convert(GroupMessageEvent event) {

    woaini.wind.bot.core.event.message.impl.GroupMessageEvent groupMessageEvent =
        new woaini.wind.bot.core.event.message.impl.GroupMessageEvent();

    String id = event.getId();
    groupMessageEvent.setId(id);

    String userId = event.getSender().getId();
    groupMessageEvent.setUserId(userId);

    String groupId = event.getGroupId();
    groupMessageEvent.setGroupId(groupId);

    Self self = new Self();
    self.setPlatform(qqbotConfig.getPlatForm());
    self.setUserId(qqbotConfig.getSelfId());

    groupMessageEvent.setSelf(self);

    groupMessageEvent.setTime(0L);
    groupMessageEvent.setType(EventType.message);

    groupMessageEvent.setMessageId(id);

    PlainText sendAble =
        (PlainText)
            event.getMessage().stream()
                .filter(d -> d instanceof PlainText)
                .findFirst()
                .orElse(null);
    if (sendAble != null) {
      groupMessageEvent.setAltMessage(sendAble.getText());
    }
    Messages messages = this.convert(event.getMessage());
    groupMessageEvent.setMessage(messages);
    return groupMessageEvent;
  }

  public Messages convert(MessageChain messageChain) {
    Messages messages = new Messages();

    for (SendAble sendAble : messageChain) {
      if (sendAble instanceof PlainText plainText) {
        messages.text(plainText.getText());
      } else if (sendAble instanceof At at) {
        messages.at(at.getTargetId());
      } else if (sendAble instanceof AtAll) {
        messages.atAll();
      }
    }

    return messages;
  }

  public void registerListener() {

    starter.registerListenerHost(
        new ListenerHost() {
          /**
           * 因为是公域 所以仅当bot被at时才能触发事件
           *
           * @param event
           */
          @EventReceiver
          public void onMessage(GroupMessageEvent event) {
            Event convert = convert(event);
            bot.addEvent(bot, convert);
          }

          @EventReceiver
          public void onMessage(FriendMessageEvent event) {
            Event convert = convert(event);
            bot.addEvent(bot, convert);
          }
        });
  }

  @Override
  public Event decode(String message) {
    return null;
  }

  @Override
  public String encode(ActionRequest action) {
    return "";
  }

  @Override
  public ActionResponse action(ActionRequest actionRequest) {


    Map<String, Object> params = actionRequest.getParams();
    String detailType = (String) params.get("detail_type");
    String userId = (String) params.get("user_id");
    String groupId = (String) params.get("group_id");


    String content = null;

    //目前只支持文本消息
    if (params.get("message") instanceof Messages messages) {
      Segment segment = messages.getElements().stream().filter(d -> d instanceof Text).findFirst().orElse(null);
      if (segment != null){
        content =( (Text)segment).getData().getText();
      }
    }
    if (StrUtil.isEmpty(content)){
      return null;
    }
    if (detailType.equals("private")){
      //私聊消息发送
      V2MsgData data = new V2MsgData().setContent(content);
      starter.getBot().userBaseV2.send(userId, data.toString(),SEND_MESSAGE_HEADERS);
    }else if (detailType.equals("group")){
      V2MsgData data = new V2MsgData().setContent(content);
      starter.getBot().groupBaseV2.send(groupId, data.toString(),GROUP_SEND_MESSAGE_HEADER);
    }
    return null;
  }

  @Override
  public void close() {}
}
